/*
 * @Author: 李无敌
 * @Date: 2025-07-25 17:00:29
 * @LastEditors: 李无敌
 * @LastEditTime: 2025-07-29 16:03:51
 * @FilePath: \nest-base\src\config\configuration.ts
 */
import { readFileSync } from 'fs';
import { join } from 'path';
import * as yaml from 'js-yaml';

export default () => {
  // 支持通过环境变量指定环境，默认为 development
  const env = process.env.NODE_ENV || 'development';
  
  // 映射环境名称到配置文件名
  const envMap = {
    'development': 'dev',
    'production': 'prod',
    'test': 'test'
  };
  const configFile = envMap[env] || 'dev';
  
  // 读取主配置文件
  const mainConfig = yaml.load(
    readFileSync(join(process.cwd(), 'config', 'application.yml'), 'utf8'),
  ) as Record<string, any>;
  
  // 读取环境特定配置文件
  const envConfig = yaml.load(
    readFileSync(join(process.cwd(), 'config', `application-${configFile}.yml`), 'utf8'),
  ) as Record<string, any>;
  
  // 合并配置
  const config = deepMerge(mainConfig, envConfig);
  
  // 支持通过环境变量覆盖敏感配置
  if (process.env.DB_HOST) config.database.host = process.env.DB_HOST;
  if (process.env.DB_PORT) config.database.port = parseInt(process.env.DB_PORT);
  if (process.env.DB_USERNAME) config.database.username = process.env.DB_USERNAME;
  if (process.env.DB_PASSWORD) config.database.password = process.env.DB_PASSWORD;
  if (process.env.DB_DATABASE) config.database.database = process.env.DB_DATABASE;
  
  if (process.env.REDIS_HOST) config.redis.host = process.env.REDIS_HOST;
  if (process.env.REDIS_PORT) config.redis.port = parseInt(process.env.REDIS_PORT);
  if (process.env.REDIS_PASSWORD) config.redis.password = process.env.REDIS_PASSWORD;
  if (process.env.REDIS_DB) config.redis.db = parseInt(process.env.REDIS_DB);
  
  if (process.env.JWT_SECRET) config.jwt.secret = process.env.JWT_SECRET;
  
  return config;
};

// 深度合并对象
function deepMerge(target: any, source: any): any {
  const result = { ...target };
  
  for (const key in source) {
    if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
      result[key] = deepMerge(result[key] || {}, source[key]);
    } else {
      result[key] = source[key];
    }
  }
  
  return result;
} 